1 /***
2 * Copyright 2003, 2004, 2005. CodeStreet LLC.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15 package com.codestreet.selector.parser;
16
17 import java.util.Map;
18 import java.util.regex.Pattern;
19 import java.util.regex.PatternSyntaxException;
20
21 /***
22 * Class to represent the <tt>LIKE</tt> operator. Immutable.
23 *
24 * @author Jawaid Hakim.
25 */
26 class OpLIKE implements IExpressionString
27 {
28 /***
29 * Ctor.
30 *
31 * @param lhs
32 * LHS.
33 * @param pattern
34 * Match pattern.
35 * @param escape
36 * Optional escape character. May be <tt>null</tt>.
37 * @throws java.lang.IllegalStateException
38 * Match pattern is invalid.
39 */
40 public OpLIKE(final IExpression lhs, final IExpression pattern,
41 final IExpression escape)
42 {
43 lhs_ = lhs;
44 pattern_ = pattern;
45
46 esc_ = escape;
47 String esc = null;
48 if (esc_ != null)
49 {
50 esc = ((String) esc_.eval(null)).trim();
51 if (esc.length() != 1)
52 throw new java.lang.IllegalStateException(
53 "ESCAPE pattern must be one character: ;" + esc + "'");
54 }
55
56 try
57 {
58 compiledPattern_ = compilePattern((String) pattern.eval(null), esc);
59 }
60 catch (PatternSyntaxException ex)
61 {
62 throw new java.lang.IllegalStateException("Invalid match pattern: "
63 + pattern);
64 }
65 }
66
67 public Object eval(final Map identifiers)
68 {
69 Object oLhs = lhs_.eval(identifiers);
70 if (!(oLhs instanceof String))
71 return Result.RESULT_UNKNOWN;
72
73 return (compiledPattern_.matcher((String) oLhs).matches()) ? Result.RESULT_TRUE
74 : Result.RESULT_FALSE;
75 }
76
77 public Object eval(final IValueProvider provider, final Object corr)
78 {
79 Object oLhs = lhs_.eval(provider, corr);
80 if (!(oLhs instanceof String))
81 return Result.RESULT_UNKNOWN;
82
83 return (compiledPattern_.matcher((String) oLhs).matches()) ? Result.RESULT_TRUE
84 : Result.RESULT_FALSE;
85 }
86
87 public String toString()
88 {
89 if (esc_ != null)
90 return lhs_.toString() + " LIKE '" + pattern_.toString() + "'";
91 else
92 return lhs_.toString() + " LIKE '" + pattern_.toString()
93 + "' ESCAPE '" + esc_.toString() + "'";
94 }
95
96 private static Pattern compilePattern(final String pattern, final String esc)
97 {
98 // In JMS the wildcard characters are '_' (match any single character)
99 // and
100 // '%' (match zero or more characters). In regular expressions the
101 // equivalent
102 // wildcard characters are '.' and '*'.
103 // We have to convert JMS wildcard characters in the pattern to regexp
104 // wildcard
105 // characters taking care of the escape character.
106 String regExp = null;
107 if (esc == null)
108 {
109 // No escape character - simply replace JMS wildcards with
110 // regular expression wildcards
111 regExp = pattern.replaceAll("_", ".{1}").replaceAll("%", ".*");
112 }
113 else
114 {
115 char cEsc = '\0';
116 StringBuffer buf = new StringBuffer();
117 cEsc = esc.charAt(0);
118 for (int i = 0; i < pattern.length(); ++i)
119 {
120 char nextChar = pattern.charAt(i);
121
122 if (nextChar != cEsc)
123 {
124 // Not an escape character - simply replace JMS wildcard
125 // characters with
126 // regular expression wildcard characters
127
128 if (nextChar == '_')
129 buf.append(".{1}");
130 else if (nextChar == '%')
131 buf.append(".*");
132 else
133 buf.append(nextChar);
134 }
135 else
136 {
137 // Escape character - replace user-defined escape character
138 // with
139 // regular expression escape character. Copy the character
140 // after
141 // the escape character as is since it is being escaped
142
143 buf.append('//');
144 ++i;
145 if (i < pattern.length())
146 {
147 buf.append(pattern.charAt(i));
148 }
149 }
150 }
151 regExp = buf.toString();
152 }
153 return Pattern.compile(regExp);
154 }
155
156 private final IExpression lhs_;
157
158 private final IExpression esc_;
159
160 private final IExpression pattern_;
161
162 private final Pattern compiledPattern_;
163 }
This page was automatically generated by Maven